package com.harmontronics.hanma.paas.paas.domain.iam.service;

import cn.hutool.core.convert.Convert;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.harmontronics.hanma.paas.paas.consts.NumberEnum;
import com.harmontronics.hanma.paas.paas.domain.iam.entity.GroupMemberUser;
import com.harmontronics.hanma.paas.paas.domain.iam.entity.MemberOrg;
import com.harmontronics.hanma.paas.paas.domain.iam.entity.valueobject.HmUserGroupMemberFields;
import com.harmontronics.hanma.paas.paas.domain.iam.service.HmUserGroupManageService;
import com.harmontronics.hanma.paas.paas.domain.organization.entity.valueobject.Constants;
import com.harmontronics.hanma.paas.paas.domain.organization.entity.valueobject.I18nKeyEnum;
import com.harmontronics.hanma.paas.paas.domain.iam.repository.persistence.HmUserGroupMemberRepository;
import com.harmontronics.hanma.paas.paas.domain.iam.entity.HmUserGroupMember;
import com.harmontronics.hanma.paas.paas.domain.iam.repository.po.HmUserGroupManagePO;
import com.harmontronics.hanma.paas.paas.domain.organization.repository.mapper.HmOrgMapper;
import com.harmontronics.hanma.paas.paas.domain.organization.repository.po.HmOrgPO;
import com.harmontronics.hanma.paas.paas.exception.ErrorKeyException;
import com.harmontronics.hanma.paas.paas.utils.MyBeanUtils;
import com.harmontronics.hanma.paas.paas.utils.StringUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.Collectors;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.harmontronics.hanma.paas.paas.common.PageBase;

import com.harmontronics.hanma.paas.paas.domain.iam.repository.mapper.HmUserGroupMemberMapper;
import com.harmontronics.hanma.paas.paas.domain.iam.repository.po.HmUserGroupMemberPO;
import java.util.List;
import org.springframework.util.StringUtils;

@Service("hmUserGroupMemberService")
@DS("#header.App-Unique")
public class HmUserGroupMemberService{

    @Autowired
    private HmUserGroupMemberRepository hmUserGroupMemberRepository;

    @Autowired
    private HmUserGroupMemberMapper hmUserGroupMemberMapper;

    @Autowired
    private HmUserGroupManageService hmUserGroupManageService;

    @Autowired
    private HmOrgMapper hmOrgMapper;

    public void remove(Long id){
            hmUserGroupMemberRepository.removeById(id);
    }

    public List<HmUserGroupMember> getList(){
        List<HmUserGroupMemberPO> pos =  hmUserGroupMemberRepository.list();
        return Convert.toList(HmUserGroupMember.class,pos) ;
    }

    public PageBase<HmUserGroupMember> getList(int pageNo,int pageSize){
        Page<HmUserGroupMemberPO> page = new Page<>(pageNo, pageSize);
        IPage<HmUserGroupMemberPO> resultPage =
                    hmUserGroupMemberRepository.selectPage(Wrappers.emptyWrapper(),page);
        return PageBase.from(resultPage,HmUserGroupMember.class);
    }

    public void create(List<HmUserGroupMember> userGroupMemberList) {
        List<HmUserGroupMember> tmpOrgMemberList =  new ArrayList<>();
        List<HmUserGroupMember> tmpUserGroupMemberCreateList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(userGroupMemberList)) {
            Long userGroupId = userGroupMemberList.get(0).getUserGroupId();
            //要创建的部门
            List<HmUserGroupMember> insertOrgMemberList = userGroupMemberList.stream().
                    filter(member-> member.getIsOrg() == NumberEnum.ONE.getNum())
                    .collect(Collectors.toList());
            //要创建的人员
            List<HmUserGroupMember> insertUserMemberList = userGroupMemberList.stream().
                    filter(member-> member.getIsOrg() == NumberEnum.ZERO.getNum())
                    .collect(Collectors.toList());
            //过滤已经存在的部门
            if(CollectionUtils.isNotEmpty(insertOrgMemberList)){
                //获取已经存在的部门
                List<HmUserGroupMember> existOrgMemberList = getOrgMember(userGroupId);
                //查询当前用户组用户的所属部门
                List<MemberOrg> memberOrgList  = hmUserGroupMemberMapper.selectOrgInfoWithMember(userGroupId);
                for (HmUserGroupMember insertOrgMember: insertOrgMemberList ) {
                    //判断插入的部门是否已存在
                    if(!existOrgMemberList.contains(insertOrgMember)){
                        tmpOrgMemberList.add(insertOrgMember);
                    }
                    //如果已创建的人员在新添加的部门中，则删除
                   if(CollectionUtils.isNotEmpty(memberOrgList)){
                       List<Long> removeIdList = new ArrayList<>();
                       for (MemberOrg memberOrg : memberOrgList) {
                           if(memberOrg.getParentIds() != null){
                               if(memberOrg.getOrgId().longValue() == insertOrgMember.getUnionId() ||
                                       memberOrg.getParentIds().contains(insertOrgMember.getUnionId().toString())){
                                   removeIdList.add(memberOrg.getId());
                               }
                           }
                       }
                       this.removeByIds(removeIdList);
                   }
                }
            }

            if(CollectionUtils.isNotEmpty(tmpOrgMemberList)){
                tmpUserGroupMemberCreateList.addAll(tmpOrgMemberList);
            }
            tmpUserGroupMemberCreateList.addAll(insertUserMemberList);



            // 按照 isOrg进行降序排序，先插入组织架构，再写入人员
            tmpUserGroupMemberCreateList.sort((o1, o2) -> o2.getIsOrg().compareTo(o1.getIsOrg()));
            List<ErrorKeyException> exceptionList = new ArrayList<>();
            for (HmUserGroupMember userGroupMemberCreate : tmpUserGroupMemberCreateList) {
                try {
                    insertSingleMember(userGroupMemberCreate);
                } catch (ErrorKeyException exception) {
                    exceptionList.add(exception);
                }
            }

            if (CollectionUtils.isNotEmpty(exceptionList)) {
                if(exceptionList.size() == tmpUserGroupMemberCreateList.size()){
                    throw exceptionList.get(0);
                }
            }
        }
    }

    private void insertSingleMember(HmUserGroupMember userGroupMemberCreate) {
        boolean isNotInGroupMember = true;
        if (NumberEnum.ZERO.getNum() == userGroupMemberCreate.getIsOrg()) {
            // 如果当前人所在的部门已经存在，则直接跳过
            List<HmUserGroupMemberPO> groupMemberList =
                    hmUserGroupMemberMapper.selectGroupMemberWithUserId(
                            userGroupMemberCreate.getUserGroupId(), userGroupMemberCreate.getUnionId());
            if (CollectionUtils.isNotEmpty(groupMemberList)) {
                isNotInGroupMember = false;
            }

            if(isNotInGroupMember){
                List<HmOrgPO> orgPoList = hmOrgMapper.selectOrgWithUserId(userGroupMemberCreate.getUnionId());
                for (int i = 0; i < orgPoList.size(); i++) {
                    HmOrgPO po = orgPoList.get(i);
                    String tmpIds = po.getParentIds();
                    if( StringUtil.isNotBlank(tmpIds)){
                        String[] parentsIds = tmpIds.replace(Constants.LEFT_SQUARE_BRACKETS,"").split(Constants.RIGHT_SQUARE_BRACKETS);
                        List<Long> parentIdList = Arrays.stream(parentsIds).map(id -> Long.parseLong(id)).collect(Collectors.toList());
                        for (int j = 0; j < parentIdList.size(); j++) {
                            Long parentId = parentIdList.get(j);
                            QueryWrapper<HmUserGroupMemberPO> queryWrapper = new QueryWrapper<>();
                            queryWrapper
                                    .eq(HmUserGroupMemberFields.USER_GROUP_ID, userGroupMemberCreate.getUserGroupId())
                                    .eq(HmUserGroupMemberFields.UNION_ID, parentId)
                                    .eq(HmUserGroupMemberFields.IS_ORG, NumberEnum.ONE.getNum());
                            List<HmUserGroupMemberPO> groupMemberPOList =
                                    getMemberWithUnionId(userGroupMemberCreate.getUserGroupId(),parentId);
                            if (CollectionUtils.isNotEmpty(groupMemberPOList)) {
                                isNotInGroupMember = false;
                                break;
                            }
                        }
                    }else{
                        Long orgId = po.getId();
                        List<HmUserGroupMemberPO> groupMemberPOList = getMemberWithUnionId(userGroupMemberCreate.getUserGroupId(),orgId);
                        if (CollectionUtils.isNotEmpty(groupMemberPOList)) {
                            isNotInGroupMember = false;
                            break;
                        }
                    }

                }
            }
        }

        if (isNotInGroupMember) {
            /**
             * 如果一个用户是父用户组的管理员，则无法再添加为子用户组的管理员或成员，添加是给出提示"该用户已经拥有该用户组的管理权限"
             * 如果一个用户是子用户组的管理员或成员，则无法再添加为父用户的管理员，添加是给出提示"该用户已经是该子用户组的管理员或成员"
             */
            if (userGroupMemberCreate.getIsOrg().equals(NumberEnum.ZERO.getNum())) {
                // 如果是管理员则不能添加为组员给出提示“该用户已经是管理员，无法再添加为组员”
                checkCurrentIsManage(
                        userGroupMemberCreate.getUnionId(), userGroupMemberCreate.getUserGroupId());

                hmUserGroupManageService.checkUser(
                        userGroupMemberCreate.getUnionId(), userGroupMemberCreate.getUserGroupId());
            }

            HmUserGroupMemberPO userGroupMember =
                    new HmUserGroupMemberPO()
                            .setDeleted(Integer.valueOf(0))
                            .setUserGroupId(userGroupMemberCreate.getUserGroupId())
                            .setUnionId(userGroupMemberCreate.getUnionId())
                            .setIsOrg(userGroupMemberCreate.getIsOrg());
            hmUserGroupMemberMapper.insert(userGroupMember);
        }
    }

    protected List<HmUserGroupMemberPO> getMemberWithUnionId(Long groupId,Long orgId){
        QueryWrapper<HmUserGroupMemberPO> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .eq(HmUserGroupMemberFields.USER_GROUP_ID, groupId)
                .eq(HmUserGroupMemberFields.UNION_ID, orgId)
                .eq(HmUserGroupMemberFields.IS_ORG, NumberEnum.ONE.getNum());
        List<HmUserGroupMemberPO> groupMemberPOList =
                hmUserGroupMemberMapper.selectList(queryWrapper);
        return groupMemberPOList;
    }

    protected void checkCurrentIsManage(Long userId, Long userGroupId) {
        List<HmUserGroupManagePO> userGroupManages =
                hmUserGroupManageService.selectGroupManageUserWithUserIdAndGroupId(userId, userGroupId);
        if (CollectionUtils.isNotEmpty(userGroupManages)) {
            throw new ErrorKeyException(I18nKeyEnum.CURRENT_USER_IS_MANAGE);
        }
    }


    public List<HmUserGroupMemberPO> selectUnDelected() {
        QueryWrapper<HmUserGroupMemberPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(HmUserGroupMemberFields.DELETED, NumberEnum.ZERO.getNum());
        return hmUserGroupMemberMapper.selectList(queryWrapper);
    }

    /**
     * 根据用户id查询所有权限
     */
    public List<HmUserGroupMemberPO> selectGroupMemberWithUserId(Long userId, Long groupId) {
        return hmUserGroupMemberMapper.selectList(
                new QueryWrapper<HmUserGroupMemberPO>()
                        .eq(HmUserGroupMemberFields.UNION_ID, userId)
                        .eq(HmUserGroupMemberFields.USER_GROUP_ID, groupId)
                        .eq(HmUserGroupMemberFields.IS_ORG, NumberEnum.ZERO.getNum()));
    }

    public List<Long> selectGroupWithUserId(Long userId) {
        List<HmUserGroupMemberPO> pos = hmUserGroupMemberMapper.selectList(
                new QueryWrapper<HmUserGroupMemberPO>()
                        .eq(HmUserGroupMemberFields.UNION_ID, userId)
                        .eq(HmUserGroupMemberFields.IS_ORG, NumberEnum.ZERO.getNum()));
        return pos.stream().map(HmUserGroupMemberPO::getUserGroupId).collect(Collectors.toList());
    }

    public void delete(Long unionId, Long userGroupId, Integer isOrg) {
        hmUserGroupMemberMapper.delete(
                new UpdateWrapper<HmUserGroupMemberPO>()
                        .eq(HmUserGroupMemberFields.UNION_ID, unionId)
                        .eq(HmUserGroupMemberFields.USER_GROUP_ID, userGroupId)
                        .eq(HmUserGroupMemberFields.IS_ORG, isOrg));
    }

    /**
     * 获取当前用户组成员列表
     */
    public List<GroupMemberUser> selectGroupMemberWithGroupId(Long groupId) {
        return hmUserGroupMemberMapper.selectGroupMemberWithGroupId(groupId);
    }

    protected List<HmUserGroupMember> getOrgMember(Long userGroupId){
        QueryWrapper<HmUserGroupMemberPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(HmUserGroupMemberFields.IS_ORG,NumberEnum.ONE.getNum()).
                eq(HmUserGroupMemberFields.USER_GROUP_ID,userGroupId).
                eq(HmUserGroupMemberFields.DELETED,NumberEnum.ZERO.getNum());
        List<HmUserGroupMemberPO> poList = hmUserGroupMemberRepository.list(queryWrapper);
        return MyBeanUtils.batchTransform(HmUserGroupMember.class,poList);
    }

    protected void removeByIds(List<Long> idList){
        hmUserGroupMemberRepository.removeByIds(idList);
    }

}